
namespace KlearTweet.Client.Initialization
{
    public class StartupService : IExceptionHandler
    {
        private readonly Shell _view;

        public StartupService(Application application, System.Collections.Generic.IDictionary<string, string> initParams)
        {
            Infrastructure.EventLogger.Verbose("KlearTweet " + GetVersion());
            _view = new Shell();
            application.RootVisual = _view;
            application.ExceptionHandler = this;

            // TODO: _view.Container.Child = _splashScreen;

            // Then, do the rest asynchronously
            Infrastructure.ThreadPoolHelper.RunOnMainThread(() => Initialize(application, initParams));
        }


        private void Initialize(Application application, System.Collections.Generic.IDictionary<string, string> initParams)
        {
            // Check for update first!
            ConfigureCheckForUpdate(application);
            CheckForUpdate(application);

            WebServices.TwitterClient.Initialize(initParams);
            var accountsManager = new AccountsManager(initParams);

            new Workspace.WorkspaceController(application, _view, accountsManager);
        }


        public void Handle(System.Windows.ApplicationUnhandledExceptionEventArgs e)
        {
            if (System.Diagnostics.Debugger.IsAttached)
                System.Diagnostics.Debugger.Break();

            // TODO: Show on SplashScreen
            e.Handled = true;
            Infrastructure.EventLogger.Error("Unhandled Exception", e.ExceptionObject);

            var message = e.ExceptionObject is System.Net.WebException // TODO: Move to Localizer
                ? "Web request failed. Your connexion or Twitter might be down." : "Unexpected error: " + e.ExceptionObject;
            DataContainers.InfoController.Show(message);
        }


        private static string GetVersion()
        {
            var asmName = System.Reflection.Assembly.GetExecutingAssembly().FullName;
            if (string.IsNullOrEmpty(asmName))
                return "?";
            var indexAfterVersion = asmName.IndexOf("Version=") + "Version=".Length;
            var versionString = asmName.Substring(indexAfterVersion, asmName.IndexOf(", Culture=") - indexAfterVersion);
            var appVersion = new System.Version(versionString);
            var compileDate = new System.DateTime(2000, 1, 1).AddDays(appVersion.Build).AddSeconds(appVersion.Revision*2);
            return appVersion + " (" + compileDate.ToString("u") + ")";
        }


        private static void ConfigureCheckForUpdate(System.Windows.Application application)
        {
            application.CheckAndDownloadUpdateCompleted += OnCheckAndDownloadUpdateCompleted;
            System.Net.NetworkInformation.NetworkChange.NetworkAddressChanged +=
                (s, e) => CheckForUpdate(application);
        }

        private static void CheckForUpdate(System.Windows.Application application)
        {
            // TODO: Should check for updates only with the consent of the user.

            if (!application.IsRunningOutOfBrowser)
                return; // Not needed
            if (!System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable())
                return; // Not possible

            application.CheckAndDownloadUpdateAsync();
        }

        private static void OnCheckAndDownloadUpdateCompleted(object sender, System.Windows.CheckAndDownloadUpdateCompletedEventArgs e)
        {
            if (e.UpdateAvailable)
            {
                DataContainers.InfoController.Show("An application update has been downloaded. " +
                                               "Restart the application to run the new version.");
            }
            else if (e.Error != null)
            {
                if (e.Error is System.PlatformNotSupportedException)
                    DataContainers.InfoController.Show("An application update is available, " +
                                                   "but it requires a new version of Silverlight. " +
                                                   "Visit the application home page to upgrade.");
                else
                    DataContainers.InfoController.Show("Error while checking for updates; please try again.\r\n" + e.Error);
            }
            //else ;// There is no update available
        }
    }
}